/* eslint indent: ["off"] */
/* eslint space-before-function-paren: ["off"] */

const Arima = require('arima')

// 引入 lodash 库，用于数据处理和操作
const _ = require('lodash')
// 精确计算
const NP = require('number-precision')
// 引入 path 模块，用于处理文件和目录路径
const path = require('path')
// 获取项目根目录
const ROOT_DIR = path.join(__dirname, '..')
// helpers 目录
const HELPERS_DIR = path.join(ROOT_DIR, 'helpers')
// 读取所有数据
let { allValues } = require(path.join(HELPERS_DIR, 'readAllValues.js'))

allValues = allValues.slice(0, 150)

const historyCount = 102
const predictionCount = 32

// 示例数据
let frontPart = allValues.slice(0, historyCount)
const backPart = allValues.slice(historyCount)

const getMultiplePredictions = (data, predictionCount) => {
  const predictions = []

  // 通过不同的 (p, d, q) 组合，训练并预测未来的值
  for (let p = 0; p <= 5; p++) {
    for (let d = 0; d <= 2; d++) {
      for (let q = 0; q <= 5; q++) {
        try {
          const model = new Arima({ p, d, q })
          model.train(data)

          // 预测未来 1 个值
          const forecast = model.predict(1) // 预测下一个值
          predictions.push(forecast[0]) // 保存预测结果

          // 如果已经获得了足够的预测值，则可以提前结束循环
          if (predictions.length >= predictionCount) {
            return predictions.slice(0, predictionCount) // 获取前 24 个预测值
          }
        } catch (error) {
          // 错误捕捉，防止某些模型训练失败
          console.log(`ARIMA(${p},${d},${q}) 训练失败:`, error)
        }
      }
    }
  }

  return predictions
}

// 去重并转换为有效的号码范围（1-49），并取整
const processPredictions = (predictions, predictionCount) => {
  const validNumbers = new Set()

  // 取整并过滤有效号码范围
  predictions.forEach((forecast) => {
    const rounded = Math.round(forecast[0]) // 取整
    if (rounded >= 1 && rounded <= 49) {
      validNumbers.add(rounded) // 添加到集合中，自动去重
    }
  })

  // 如果数量不足 24 个，再通过随机选择填充
  const validArray = Array.from(validNumbers)
  while (validArray.length < predictionCount) {
    const randomNum = Math.floor(Math.random() * 49) + 1
    if (!validArray.includes(randomNum)) {
      validArray.push(randomNum)
    }
  }

  return validArray
}

const getArimaList = (historicalData, predictionCount) => {
  // 获取 24 个不同的预测值
  const predictions = getMultiplePredictions(historicalData, predictionCount)
  // 处理预测结果，去重并保留有效号码
  const processedPredictions = processPredictions(predictions, predictionCount)
  return processedPredictions
}

// console.log(
//   `未来 ${predictionCount} 个有效预测值:`,
//   processedPredictions.sort((a, b) => a - b)
// )
// console.log(allValues[historyCount])

const accuracyList = backPart.map((item) => {
  const historicalData = frontPart.map((item) => Number(item.number))
  const processedPredictions = getArimaList(historicalData, predictionCount)

  frontPart = [...frontPart, item]

  return {
    ...item,
    accuracy: processedPredictions.map(Number).includes(Number(item.number)) ? 1 : 0
  }
})

console.log(accuracyList)

const accuracy = accuracyList.map((item) => item.accuracy)
console.log(accuracy)

const accuracyCount = _.countBy(accuracy)
console.log(accuracyCount)

const successRate = NP.times(NP.round(NP.divide(accuracyCount[1], accuracy.length), 2), 100)

console.log(`${accuracyCount[1]} / ${accuracy.length} = ${successRate}%`)

